package cn.zlp.order.service.impl;

import cn.zlp.basic.service.impl.BaseServiceImpl;
import cn.zlp.basic.util.CodeGenerateUtils;
import cn.zlp.basic.util.LoginContextUtil;
import cn.zlp.order.domain.OrderAddress;
import cn.zlp.order.domain.ProductOrder;
import cn.zlp.order.domain.ProductOrderDetail;
import cn.zlp.order.mapper.OrderAddressMapper;
import cn.zlp.order.mapper.ProductOrderDetailMapper;
import cn.zlp.order.mapper.ProductOrderMapper;
import cn.zlp.order.service.IProductOrderService;
import cn.zlp.org.mapper.ShopMapper;
import cn.zlp.pay.constants.PayConstants;
import cn.zlp.pay.domain.PayBill;
import cn.zlp.pay.mapper.PayBillMapper;
import cn.zlp.pay.service.IPayBillService;
import cn.zlp.product.domain.Product;
import cn.zlp.product.mapper.ProductMapper;
import cn.zlp.quartz.constant.JobConstants;
import cn.zlp.quartz.dto.QuartzJobInfo;
import cn.zlp.quartz.service.IQuartzService;
import cn.zlp.user.domain.Logininfo;
import cn.zlp.user.domain.User;
import cn.zlp.user.domain.UserAddress;
import cn.zlp.user.mapper.UserAddressMapper;
import cn.zlp.user.mapper.UserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class ProductOrderServiceImpl extends BaseServiceImpl<ProductOrder> implements IProductOrderService {

    @Autowired(required = false)
    private ProductOrderMapper productOrderMapper;

    @Autowired(required = false)
    private UserAddressMapper userAddressMapper;

    @Autowired(required = false)
    private OrderAddressMapper orderAddressMapper;

    @Autowired(required = false)
    private ProductMapper productMapper;

    @Autowired(required = false)
    private ProductOrderDetailMapper productOrderDetailMapper;

    @Autowired(required = false)
    private PayBillMapper payBillMapper;

    @Autowired(required = false)
    private IPayBillService payBillService;

    @Autowired(required = false)
    private IQuartzService quartzService;

    @Autowired(required = false)
    private UserMapper userMapper;

    @Autowired(required = false)
    private ShopMapper shopMapper;

    @Override
    public String submit(Map<String, Object> params, HttpServletRequest request) {
        // 获取用户地址id
        Long addressId = Long.parseLong(params.get("address_id").toString());
        // 获取服务id
        Long productId = Long.parseLong(params.get("product_id").toString());
        // 获取支付方式
        Long pay_method = Long.parseLong(params.get("pay_method").toString());
        // 获取服务方式
        Long service_method = Long.parseLong(params.get("service_method").toString());
        // 根据用户地址id查询用户地址
        Product product = productMapper.loadById(productId);
//        UserAddress userAddress = userAddressMapper.loadById(addressId);
        // 2.设置领养用户
        Logininfo logininfo = LoginContextUtil.getLogininfo(request);
        // 根据登录信息获取用户对象
        User user = userMapper.findByLogininfoId(logininfo.getId());
        //1创建订单
        //1.1 创建订单
        /* todo */
        ProductOrder productOrder = getProductOrder(params,product,user);
        // 保存订单
        productOrderMapper.save(productOrder);
        // 暂时不用
//        //1.2 保存关联表 orderAdress productOrderDetail
//        OrderAddress orderAddress = userAddress2OrderAddress(userAddress,productOrder);
//        // 保存订单地址
//        orderAddressMapper.save(orderAddress);

        // 保存服务订单明细,防止售价改后订单改变,因为和服务字段一致,所以用服务转
        ProductOrderDetail productOrderDetail = product2productOrderDetail(product);
        // 设置服务订单id
        productOrderDetail.setOrder_id(productOrder.getId());
        // 保存
        productOrderDetailMapper.save(productOrderDetail);

        // 2 创建支付单
        PayBill payBill = initPayBill(pay_method, productOrder, user);
        payBillMapper.save(payBill);

        // 4.2调用支付单支付请求接口,这样可以解耦,以后支付单请求直接传入支付单调用接口就行了
        String payData = payBillService.payRequest(payBill);
        return payData;
    }

    /**
     * 暂时不需要
     * @param userAddress
     * @param productOrder
     * @return
     */
    private OrderAddress userAddress2OrderAddress(UserAddress userAddress, ProductOrder productOrder) {
        // 创建订单地址对象
        OrderAddress orderAddress = new OrderAddress();
        // 直接拷贝相同属性的值
        BeanUtils.copyProperties(userAddress,orderAddress);
        // 设置订单id
        orderAddress.setOrder_id(productOrder.getId());
        // 设置订单单号
        orderAddress.setOrderSn(productOrder.getOrderSn());
        // 设置创建时间
        orderAddress.setCreateTime(new Date());
        return orderAddress;
    }

    /**
     * 超时未支付取消订单
     * @param orderId
     */
    @Override
    public void cancelOrder(Long orderId) {
        // 根据服务订单id获取服务订单
        ProductOrder productOrder = productOrderMapper.loadById(orderId);
        if(productOrder.getState()!=-1){ // 判断订单是否取消
            // 设置状态,取消
            productOrder.setState(-1);
            productOrderMapper.update(productOrder);
        }
        // 根据支付单唯一标识获取支付单
        String paySn = productOrder.getPaySn();
        PayBill payBill = payBillMapper.loadByUnionPaySn(paySn);
        if (payBill.getState()!=-1){
            payBill.setState(-1);
            payBill.setUpdateTime(new Date());
            payBillMapper.update(payBill);
        }

    }

    private PayBill initPayBill(Long pay_method, ProductOrder productOrder,User user) {
        // 新建一个支付单对象
        PayBill payBill = new PayBill();
        // 因为虽然订单和支付单属性一样,但属性名不一样,所以只有挨个设置
        // 设置摘要
        payBill.setDigest(productOrder.getDigest());
        // 设置售价
        payBill.setMoney(productOrder.getPrice());
        // 最后支付时间
        payBill.setLastPayTime(new Date(System.currentTimeMillis() + PayConstants.ORDER_TIMEOUT));
        // 设置支付渠道
        payBill.setPayChannel(pay_method);
        // 设置支付单唯一标识
        payBill.setUnionPaySn(productOrder.getPaySn());
        // 设置业务类型,区分什么订单,这里直接用常量类的字段,服务单
        payBill.setBusinessType(PayConstants.BUSINESS_TYPE_PRODUCT);
        // 设置业务键,我们治理设置的id,用来区分订单
        payBill.setBusinessKey(productOrder.getId());
        // 设置支付用户id
        payBill.setUser_id(user.getId());
        // 设置支付用户昵称
        payBill.setNickName(user.getUsername());
        // 设置收款店铺id
        payBill.setShop_id(0L);
        QuartzJobInfo info = new QuartzJobInfo();
        // 设置定时作业类型
        info.setType(JobConstants.OVER_TIME_NO_PAY_PRODUCT);
        // 设置定时作业名字
        info.setJobName(JobConstants.OVER_TIME_NO_PAY_PRODUCT + productOrder.getPaySn());
        // 设置定时作业触发时间
        info.setFireDate(productOrder.getLastPayTime());
        Map<String,Object> map = new HashMap<>();
        map.put("orderId",productOrder.getId());
        info.setParams(map);
        quartzService.add(info);
        // 返回支付单对象
        return payBill;
    }

    private ProductOrderDetail product2productOrderDetail(Product product) {
        ProductOrderDetail productOrderDetail = new ProductOrderDetail();
        // 直接复制
        BeanUtils.copyProperties(product,productOrderDetail);
        return productOrderDetail;
    }

    private ProductOrder getProductOrder(Map<String, Object> params,Product product, User user) {
        // 获取服务数量
        Long productNum = Long.parseLong(params.get("product_num").toString());
        ProductOrder productOrder = new ProductOrder();

        productOrder.setDigest("[服务订单]购买"+productNum+"次"+product.getName()+"服务！");
        // 设置订单支付状态为待支付
        productOrder.setState(0);
        // 设置售价,单价乘上数量
        BigDecimal price  = product.getSaleprice()
                .multiply(new BigDecimal(productNum));
        productOrder.setPrice(price);
        // 设置订单唯一标识
        productOrder.setOrderSn(CodeGenerateUtils.generateOrderSn(user.getId()));
        // 设置最后支付时间
        Date lastPayTime = new Date(System.currentTimeMillis()+PayConstants.ORDER_TIMEOUT); //当前时间+15分钟
        productOrder.setLastPayTime(lastPayTime);
        // 设置服务id
        productOrder.setProduct_id(product.getId());
        // 设置购买用户id
        productOrder.setUser_id(user.getId());
//        // 根据用户地址分配最近店铺
//        Shop nearestShop = DistanceUtil.getNearestShop(DistanceUtil.getPoint(userAddress.getFullAddress()), shopMapper.loadAll());
//        // 设置店铺id
//        productOrder.setShop_id(nearestShop.getId());
        // 设置支付单唯一标识
        productOrder.setPaySn(CodeGenerateUtils.generateUnionPaySn());
        return productOrder;
    }
}
